﻿
using Xacml.Core;
using System;
using System.Xml;

namespace Xacml.Core.Policy
{
  public abstract class TargetMatchBaseReadWrite : XacmlElement
  {
    private string _id;
    private AttributeValueElementReadWrite _attributeValue;
    private AttributeReferenceBase _attributeReference;

    public virtual string MatchId
    {
      get
      {
        return this._id;
      }
      set
      {
        this._id = value;
      }
    }

    public virtual AttributeValueElementReadWrite AttributeValue
    {
      get
      {
        return this._attributeValue;
      }
      set
      {
        this._attributeValue = value;
      }
    }

    public virtual AttributeReferenceBase AttributeReference
    {
      get
      {
        return this._attributeReference;
      }
      set
      {
        this._attributeReference = value;
      }
    }

    protected TargetMatchBaseReadWrite(string matchId, AttributeValueElementReadWrite attributeValue, AttributeReferenceBase attributeReference, XacmlVersion schemaVersion)
      : base(XacmlSchema.Policy, schemaVersion)
    {
      this._id = matchId;
      this._attributeValue = attributeValue;
      this._attributeReference = attributeReference;
    }

    protected TargetMatchBaseReadWrite(XmlReader reader, string matchNodeName, string attributeDesignatorNode, XacmlVersion schemaVersion)
      : base(XacmlSchema.Policy, schemaVersion)
    {
      if (reader.LocalName == matchNodeName && this.ValidateSchema(reader, schemaVersion))
      {
        this._id = reader.GetAttribute("MatchId");
        while (reader.Read())
        {
          if (reader.LocalName == "AttributeValue" && this.ValidateSchema(reader, schemaVersion))
            this._attributeValue = new AttributeValueElementReadWrite(reader, schemaVersion);
          else if (reader.LocalName == attributeDesignatorNode && this.ValidateSchema(reader, schemaVersion))
            this._attributeReference = (AttributeReferenceBase) this.CreateAttributeDesignator(reader);
          else if (reader.LocalName == "AttributeSelector" && this.ValidateSchema(reader, schemaVersion))
            this._attributeReference = (AttributeReferenceBase) new AttributeSelectorElement(reader, schemaVersion);
          else if (reader.LocalName == matchNodeName && reader.NodeType == XmlNodeType.EndElement)
            break;
        }
      }
      else
        throw new Exception(Resource.ResourceManager[Resource.MessageKey.exc_invalid_node_name, new object[1]
        {
          (object) reader.LocalName
        }]);
    }

    protected abstract AttributeDesignatorBase CreateAttributeDesignator(XmlReader reader);
  }
}
